module  MEMORY  ( 
        //      Inputs 
        ex_mem,
        addr_in,
        alu_out_pl,
        rf1_pl,
        ext_pl,
        inst,
        createdump,
        clk,
        rst,
        //      Outputs
        mem_wb,
        addr_out_pl,
        addr_out,
        mem_pl,
        lbi_pl,
        inst_pl, 
        err     );

        input   [11:0]  ex_mem;
        input   [15:0]  addr_in;
        input   [15:0]  alu_out_pl;
        input   [15:0]  rf1_pl;
        input   [15:0]  ext_pl;
        input   [8:0]   inst;
        input           createdump;
        input           ckl;
        input           rst;

        output  [3:0]   mem_wb;
        output  [15:0]  addr_out_pl;
        output  [15:0]  addr_out;
        output  [15:0]  mem_pl;
        output  [15:0]  lbi_pl;
        output  [8:0]   inst_pl;
        output          err;
        /*      CTRL SIGNALS IN MEMORY STAGE    */
        wire    [7:0]   mem;
        wire            mem_rd;
        wire            mem_wr;
        wire    [2:0]   branch;
        wire            lbi;
        wire            j;
        wire            jr;
        assign          mem = ex_mem[11:4];
        assign          mem_rd = mem[7];
        assign          mem_wr = mem[6];
        assign          branch = mem[5:3];
        assign          lbi = mem[2];
        assign          j = mem[1];
        assign          jr = mem[0];
        /*      CTRL SIGNALS IN FOLLOWING STAGE         */
        dff     mem_wb[3:0]
        (
                .q ( mem_wb ),
                .d ( ex_mem[3:0] ),
                .clk ( clk ),
                .rst ( rst )
        );
        /*      PIPELINE : DATA PATH    */
        dff     addr[15:0]
        (
                .q ( addr_out_pl ),
                .d ( addr_in ),
                .clk ( clk ),
                .rst ( rst )
        );
        wire    [15:0]  mem_out;
        dff     mem_out[15:0]
        (
                .q ( mem_pl ),
                .d ( mem_out ),
                .clk ( clk ),
                .rst ( rst )
        );
        wire    [15:0]  lbi_out;
        dff     lbi_out[15:0]
        (
                .q ( lbi_pl ),
                .d ( lbi_out ),
                .clk ( clk ),
                .rst ( rst )
        );
        dff     inst[8:0]
        (
                .q ( inst_pl ),
                .d ( inst ),
                .clk ( clk ),
                .rst ( rst )
        );
        /*      UNPIPELINED : DATA PATH */
        wire    jump;
        branch  branch 
        (
                .branch(branch),
                .j(j),
                .rs(rd_data1),
                .jump(jump) 
        );
        assign  addr_out = (jr==1'b1)?alu_out
                :   (jump==1'b1)?branch_addr:pc_plus_2;

        memory2c d_mem
        (
                .data_out(mem_out),
                .data_in(rd_data2),
                .addr(alu_out),
                .clk(clk),
                .rst(rst),
                .enable(mem_rd | mem_wr),
                .wr(mem_wr),
                .createdump(createdump)
        );
        assign  lbi_out = lbi ? alu_out_pl : ext_pl;        
endmodule 
